/*
 * Temp_Hum.c
 *
 * Created: 1/18/2014 12:31:11 PM
 *  Author: Hp-Minion
 */ 
/*****************************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "General.h"
#include "Temp_Hum.h"
#include "Port.h"
#include "Timer.h"
#include "External_Interrupt.h"
#include "USART_0.h"
/*****************************************************************************************/
volatile unsigned char data[40];
volatile unsigned char lvl = 0;
volatile unsigned char transferData = 0;
volatile unsigned char countBits = 0;
volatile unsigned char selectedPin = 0;
/*****************************************************************************************/
void TempHum_Init (unsigned char pin)
{
	PinMode(pin,'D', OUTPUT);	// set pin as output first for trigger sensor
	DigitalWrite(pin, HIGH);	// set pin high until we start sending the trigger
}
/*****************************************************************************************/
void readData (unsigned char pin)
{
    unsigned char timePassed = 0;
    
    if (lvl && DigitalRead(pin))
    {
        //start timer
        Start_Timer0();
    } 
    else
    {
		static unsigned char index = 0;
		// reset index in case of multiple calls
		if (index == 40)
		{
			index = 0;
		}
		
        //stop timer and get timer counts
        timePassed = (unsigned char)Stop_Timer0();
		/*
		    - one timer count equals 4us
			- the time for bit '1' is 23us and for '0' is 70 us
			- check for more than 24us to get the bit value
			- 4us * 8 = 32us -> ore than enough to get the bit value.
		*/
        
        if (timePassed > 8)
        {
            // data sent is bit '1'
            data[index] = 1;
        } 
        else
        {
            // data sent is bit '0'
            data[index] = 0;
        }
		index++;
    }
}
/*****************************************************************************************/
StatusCodes TempHum_Handler ( unsigned char intPin, AreaConditions *garden )
{
    StatusCodes status = STATUS_CODE_UNDEFINED;
	unsigned char dataValue[5] = {0,0,0,0,0};
	
	// get the PIN #
	selectedPin = intPin;
	
	DigitalWrite(selectedPin, LOW);
	Delay_ms(18);
	DigitalWrite(selectedPin, HIGH);
	Delay_us(40);
	// wait for response
    // change port to input
	PinMode(selectedPin, 'D', INPUT);
	Delay_us(40);
	
	if (DigitalRead(selectedPin))
	{
		status = STATUS_CODE_FAIL;
        DigitalWrite(ARDUINO_LED, HIGH);
		
#       ifdef DEBUG_LVL_0
		serialPrint("#1 NOT met\n");
#       endif
	}
	Delay_us(80);
	
	if (!DigitalRead(selectedPin))
	{
		status = STATUS_CODE_FAIL;
		DigitalWrite(ARDUINO_LED, HIGH);
		
#       ifdef DEBUG_LVL_0
		serialPrint("#2 NOT met\n");
#		endif
	}
	
	// ready for data collection
#   ifdef DEBUG_LVL_1
	serialPrint("ready\n");
#	endif

    // initialize and enable external interrupt
    ExtInt_SelectINT(selectedPin, TRUE);
    // wait for the data to be collected
    while(!transferData);
	
	// data collected, prepare pin for next round
#   ifdef DEBUG_LVL_1
	serialPrint("done\n");
#	endif

    // disable external interrupt
    ExtInt_SelectINT(selectedPin, FALSE);
	PinMode(selectedPin, 'D', OUTPUT);
	DigitalWrite(selectedPin, HIGH);
    transferData = 0;
		
    //re-construct data
    for (int i=0; i<5; i++)
    {
        for (int j=0; j<8; j++)
        {            
			dataValue[i] |= (data[8*i + j] << (7-j));
#           ifdef DEBUG_LVL_2
            char nString[USART_MAX_STR_PRINT_SIZE];
			sprintf(nString, );
		    serialPrint(nString);
#           endif
        }
    }
	
#   ifdef DEBUG_LVL_1
	for (int i=0; i<5; i++)
	{
		char nString[USART_MAX_STR_PRINT_SIZE];
		sprintf(nString, "\n byte:%i-%i", i, dataValue[i]);
		serialPrint(nString);
	}
#   endif

	//check check-sum
	if (dataValue[4] == (dataValue[0] + dataValue[1] + dataValue[2] + dataValue[3]))
	{
		// data is ready and correct
		garden->humidity = dataValue[0];
		garden->temperature = dataValue[2];
		
		status = STATUS_CODE_SUCCESS;
#       ifdef DEBUG_LVL_0
		char nStringH[USART_MAX_STR_PRINT_SIZE];
	    char nStringT[USART_MAX_STR_PRINT_SIZE];
	
		(void)sprintf(nStringH, "\n H:%i.%i", dataValue[0], dataValue[1]);
		serialPrint(nStringH);
		
		(void)sprintf(nStringT, "\n T:%i.%i", dataValue[2], dataValue[3]);
		serialPrint(nStringT);
#       endif	
	}	
	else// -> data received is rubbish
	{
		status = STATUS_CODE_ERROR;
		
#		ifdef DEBUG_LVL_0
	    serialPrint("rubbish\n");
#		endif
	}
	return status;
}
/*****************************************************************************************/
void TempHum_ISR(void)
{
    lvl = ~lvl;
    countBits++;
	if (countBits > 2)
	{
		// don't read the first, just a trigger
	    readData(selectedPin);
	}		
    if (countBits == 82)
    {
        transferData = 1;
        lvl = 0;
        countBits = 0;
    }
}
/*****************************************************************************************/
ISR(INT0_vect)
{
//#   ifdef DEBUG
	//serialPrint("ISR\n");
//#	endif
//
	TempHum_ISR();
}
/*****************************************************************************************/